
package com.learn.SingleTon;

import java.lang.reflect.InvocationTargetException;

/**
 * 懒汉式
 * 1.DCL懒汉式  双重校验锁  添加了volite关键字
 * 2.三重锁  防止反射
 */
public class Lazy {
    //防止指令重排
    private static volatile Lazy lazy;

    private Lazy() {
//        synchronized (Lazy.class){
//            if(lazy!=null){
//                throw new RuntimeException("不试图使用反射破坏单例!");
//            }
//        }
    }

    public static Lazy getLazySingleTon(){
        if(lazy!=null){
            //加锁防止线程占用
            synchronized (Lazy.class){
                if(lazy!=null){
                    lazy = new Lazy();
                    /**
                     * 1.分配内存
                     * 2.执行构造方法  初始化对象
                     * 3.把对象指向内存空间
                     *
                     * 线程A可能先执行完3
                     * 线程B进来发现已经为对象分配了内存空间就认为有值,直接返回未被构造的对象
                     * 所以要使用volatile防止指令重排
                     */
                }
            }
        }
        return lazy;
    }

    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//        Lazy lazySingleTon = Lazy.getLazySingleTon();
//
//        //使用反射可以破坏DCL的结构
//        Class<Lazy> lazyClass = Lazy.class;
//        Constructor<Lazy> declaredConstructor = lazyClass.getDeclaredConstructor(null);
//        declaredConstructor.setAccessible(true);
//        Lazy lazy = declaredConstructor.newInstance(null);
//
//        System.out.println(lazySingleTon);
//        System.out.println(lazy);

        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"="+getLazySingleTon());
            },i+"").start();
        }

    }
}
